/*****************************************************************************
*
*  PROJECT:     Native Executive
*  LICENSE:     See LICENSE in the top level directory
*  FILE:        NativeExecutive/CExecutiveManager.internal.h
*  PURPOSE:     Main internal include of the NativeExecutive framework
*  DEVELOPERS:  Martin Turski <wordwhirl@outlook.de>
*
*  Multi Theft Auto is available from http://www.multitheftauto.com/
*
*****************************************************************************/

#ifndef _NATIVE_EXECUTIVE_MANAGER_INTERNAL_
#define _NATIVE_EXECUTIVE_MANAGER_INTERNAL_

// Very important modules.
#include "CExecutiveManager.rwlock.internal.h"

// Need-to-know things.
#include "CExecutiveManager.thread.internal.h"

BEGIN_NATIVE_EXECUTIVE

// Memory allocator used in this environment.
struct nativeExecutiveAllocator
{
    inline void* Allocate( size_t memSize )
    {
        return malloc( memSize );
    }

    inline void Free( void *memPtr, size_t memSize )
    {
        return free( memPtr );
    }
};

namespace ExecutiveManager
{
    extern nativeExecutiveAllocator moduleAllocator;
};

struct CExecutiveGroupImpl;
struct CFiberImpl;

class CExecutiveManagerNative : public CExecutiveManager
{
public:
    // We do not want the runtime to create us.
    // Instead we expose a factory that has to create us.

    CExecutiveManagerNative( void );
    ~CExecutiveManagerNative( void );

    void            InitThreads         ( void );
    void            ShutdownThreads     ( void );

    void            PushFiber           ( CFiberImpl *fiber );
    void            PopFiber            ( void );

    // This is the native representation of the executive manager.
    // Every alive type of CExecutiveManager should be of this type.

    ExecutiveManager::threadPluginContainer_t threadPlugins;

    CReadWriteLock *threadPluginsLock;

    bool isTerminating;         // if true then no new objects are allowed to spawn anymore.
    bool isRuntimeTerminating;  // if true allow no more new fibers and executive groups.

    RwList <CExecThreadImpl> threads;
    RwList <CFiberImpl> fibers;
    RwList <CExecTask> tasks;
    RwList <CExecutiveGroupImpl> groups;

    CExecutiveGroupImpl *defGroup;      // default group that all fibers are put into at the beginning.

    double frameTime;
    double frameDuration;

    double GetFrameDuration( void )
    {
        return frameDuration;
    }

    readWriteLockEnv_t readWriteLockEnv;
};

typedef StaticPluginClassFactory <CExecutiveManagerNative> executiveManagerFactory_t;

extern executiveManagerFactory_t executiveManagerFactory;

END_NATIVE_EXECUTIVE

#endif //_NATIVE_EXECUTIVE_MANAGER_INTERNAL_